From 596da843126094506f2d2e440db71c392b2b72c1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 21 Oct 2010 13:09:25 +0200 Subject: [PATCH] Make GtkEntry a no-window widget Use input-only windows for capturing input, and just draw onto the parent window. This allows themes to make entries with rounded corners. Patch by Boram Park. https://bugzilla.gnome.org/show_bug.cgi?id=632736 --- docs/reference/gtk/gtk3-sections.txt | 2 - gtk/gtk.symbols | 2 - gtk/gtkentry.c | 273 +++++++++------------------ gtk/gtkentry.h | 4 - gtk/gtkentrycompletion.c | 10 +- gtk/gtkspinbutton.c | 11 +- 6 files changed, 99 insertions(+), 203 deletions(-) diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index fc54a63b35..2cb1d8e7ca 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -1031,8 +1031,6 @@ gtk_entry_set_icon_tooltip_markup gtk_entry_get_icon_tooltip_markup gtk_entry_set_icon_drag_source gtk_entry_get_current_icon_drag_source -gtk_entry_get_icon_window -gtk_entry_get_text_window GTK_ENTRY diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index c75106232d..88de0b8f65 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -1083,7 +1083,6 @@ gtk_entry_get_icon_stock gtk_entry_get_icon_storage_type gtk_entry_get_icon_tooltip_markup gtk_entry_get_icon_tooltip_text -gtk_entry_get_icon_window gtk_entry_get_inner_border gtk_entry_get_invisible_char gtk_entry_get_layout @@ -1097,7 +1096,6 @@ gtk_entry_get_text_length gtk_entry_get_type G_GNUC_CONST gtk_entry_get_visibility gtk_entry_get_width_chars -gtk_entry_get_text_window gtk_entry_im_context_filter_keypress gtk_entry_layout_index_to_text_index gtk_entry_new diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 67f7565657..154c1def7a 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -265,8 +265,7 @@ static void gtk_entry_size_allocate (GtkWidget *widget, static void gtk_entry_draw_frame (GtkWidget *widget, cairo_t *cr); static void gtk_entry_draw_progress (GtkWidget *widget, - cairo_t *cr, - GdkWindow *window); + cairo_t *cr); static gint gtk_entry_draw (GtkWidget *widget, cairo_t *cr); static gint gtk_entry_button_press (GtkWidget *widget, @@ -468,7 +467,7 @@ static void get_text_area_size (GtkEntry *entry, gint *y, gint *width, gint *height); -static void get_widget_window_size (GtkEntry *entry, +static void get_frame_size (GtkEntry *entry, gint *x, gint *y, gint *width, @@ -2260,6 +2259,7 @@ gtk_entry_init (GtkEntry *entry) GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); gtk_widget_set_can_focus (GTK_WIDGET (entry), TRUE); + gtk_widget_set_has_window (GTK_WIDGET (entry), FALSE); entry->editable = TRUE; entry->visible = TRUE; @@ -2622,11 +2622,9 @@ realize_icon_info (GtkWidget *widget, attributes.width = 1; attributes.height = 1; attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); + attributes.wclass = GDK_INPUT_ONLY; attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | + attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | @@ -2634,14 +2632,12 @@ realize_icon_info (GtkWidget *widget, GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; + attributes_mask = GDK_WA_X | GDK_WA_Y; icon_info->window = gdk_window_new (gtk_widget_get_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (icon_info->window, widget); - gdk_window_set_background (icon_info->window, - >k_widget_get_style (widget)->base[gtk_widget_get_state (widget)]); gtk_widget_queue_resize (widget); } @@ -2715,21 +2711,21 @@ gtk_entry_realize (GtkWidget *widget) GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; + gint frame_x, frame_y; int i; gtk_widget_set_realized (widget, TRUE); + window = gtk_widget_get_parent_window (widget); + gtk_widget_set_window (widget, window); + g_object_ref (window); + entry = GTK_ENTRY (widget); priv = GTK_ENTRY_GET_PRIVATE (entry); attributes.window_type = GDK_WINDOW_CHILD; - - get_widget_window_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); - - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); + attributes.wclass = GDK_INPUT_ONLY; attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | + attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | @@ -2737,21 +2733,23 @@ gtk_entry_realize (GtkWidget *widget) GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - - window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, entry); + attributes_mask = GDK_WA_X | GDK_WA_Y; get_text_area_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); - + + get_frame_size (entry, &frame_x, &frame_y, NULL, NULL); + attributes.x += frame_x; + attributes.y += frame_y; + if (gtk_widget_is_sensitive (widget)) { attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; } - entry->text_area = gdk_window_new (window, &attributes, attributes_mask); + entry->text_area = gdk_window_new (gtk_widget_get_window (widget), + &attributes, + attributes_mask); gdk_window_set_user_data (entry->text_area, entry); @@ -2760,11 +2758,6 @@ gtk_entry_realize (GtkWidget *widget) gtk_widget_style_attach (widget); - style = gtk_widget_get_style (widget); - state = gtk_widget_get_state (widget); - gdk_window_set_background (window, &style->base[state]); - gdk_window_set_background (entry->text_area, &style->base[state]); - gdk_window_show (entry->text_area); gtk_im_context_set_client_window (entry->im_context, entry->text_area); @@ -2918,10 +2911,12 @@ place_windows (GtkEntry *entry) GtkWidget *widget = GTK_WIDGET (entry); GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); gint x, y, width, height; + gint frame_x, frame_y; GtkAllocation primary; GtkAllocation secondary; EntryIconInfo *icon_info = NULL; + get_frame_size (entry, &frame_x, &frame_y, NULL, NULL); get_text_area_size (entry, &x, &y, &width, &height); get_icon_allocations (entry, &primary, &secondary); @@ -2934,6 +2929,13 @@ place_windows (GtkEntry *entry) x += primary.width; width -= primary.width + secondary.width; + x += frame_x; + y += frame_y; + primary.x += frame_x; + primary.y += frame_y; + secondary.x += frame_x; + secondary.y += frame_y; + if ((icon_info = priv->icons[GTK_ENTRY_ICON_PRIMARY]) != NULL) gdk_window_move_resize (icon_info->window, primary.x, primary.y, @@ -2966,7 +2968,7 @@ gtk_entry_get_text_area_size (GtkEntry *entry, _gtk_entry_get_borders (entry, &xborder, &yborder); if (gtk_widget_get_realized (widget)) - frame_height = gdk_window_get_height (gtk_widget_get_window (widget)); + get_frame_size (entry, NULL, NULL, NULL, &frame_height); else frame_height = requisition.height; @@ -3005,11 +3007,11 @@ get_text_area_size (GtkEntry *entry, static void -get_widget_window_size (GtkEntry *entry, - gint *x, - gint *y, - gint *width, - gint *height) +get_frame_size (GtkEntry *entry, + gint *x, + gint *y, + gint *width, + gint *height) { GtkAllocation allocation; GtkRequisition requisition; @@ -3077,13 +3079,8 @@ gtk_entry_size_allocate (GtkWidget *widget, if (gtk_widget_get_realized (widget)) { - gint x, y, width, height; GtkEntryCompletion* completion; - get_widget_window_size (entry, &x, &y, &width, &height); - gdk_window_move_resize (gtk_widget_get_window (widget), - x, y, width, height); - place_windows (entry); gtk_entry_recompute (entry); @@ -3250,11 +3247,17 @@ gtk_entry_draw_frame (GtkWidget *widget, GdkWindow *window; gint x = 0, y = 0, width, height; GtkStateType state; + GtkAllocation allocation; + gint frame_x, frame_y; + + cairo_save (cr); window = gtk_widget_get_window (widget); - width = gdk_window_get_width (window); - height = gdk_window_get_height (window); + get_frame_size (GTK_ENTRY (widget), &frame_x, &frame_y, &width, &height); + gtk_widget_get_allocation (widget, &allocation); + + cairo_translate (cr, frame_x - allocation.x, frame_y - allocation.y); /* Fix a problem with some themes which assume that entry->text_area's * width equals widget->window's width @@ -3282,12 +3285,17 @@ gtk_entry_draw_frame (GtkWidget *widget, state = gtk_widget_has_focus (widget) ? GTK_STATE_ACTIVE : gtk_widget_get_state (widget); + gtk_paint_flat_box (style, cr, + state, GTK_SHADOW_NONE, + widget, "entry_bg", + x, y, width, height); + gtk_paint_shadow (style, cr, state, priv->shadow_type, widget, "entry", x, y, width, height); - gtk_entry_draw_progress (widget, cr, window); + gtk_entry_draw_progress (widget, cr); if (gtk_widget_has_focus (widget) && !priv->interior_focus) { @@ -3301,6 +3309,8 @@ gtk_entry_draw_frame (GtkWidget *widget, widget, "entry", 0, 0, width, height); } + + cairo_restore (cr); } static void @@ -3337,15 +3347,17 @@ get_progress_area (GtkWidget *widget, GtkEntryPrivate *private = GTK_ENTRY_GET_PRIVATE (widget); GtkEntry *entry = GTK_ENTRY (widget); GtkBorder progress_border; + gint frame_width, frame_height; + get_frame_size (entry, NULL, NULL, &frame_width, &frame_height); gtk_entry_get_progress_border (widget, &progress_border); *x = progress_border.left; *y = progress_border.top; - *width = gdk_window_get_width (gtk_widget_get_window (widget)) + *width = frame_width - progress_border.left - progress_border.right; - *height = gdk_window_get_height (gtk_widget_get_window (widget)) + *height = frame_height - progress_border.top - progress_border.bottom; if (gtk_widget_has_focus (widget) && !private->interior_focus) @@ -3389,8 +3401,7 @@ get_progress_area (GtkWidget *widget, static void gtk_entry_draw_progress (GtkWidget *widget, - cairo_t *cr, - GdkWindow *window) + cairo_t *cr) { gint x, y, width, height; GtkStateType state; @@ -3400,16 +3411,6 @@ gtk_entry_draw_progress (GtkWidget *widget, if ((width <= 0) || (height <= 0)) return; - if (window != gtk_widget_get_window (widget)) - { - gint pos_x, pos_y; - - gdk_window_get_position (window, &pos_x, &pos_y); - - x -= pos_x; - y -= pos_y; - } - state = GTK_STATE_SELECTED; if (!gtk_widget_get_sensitive (widget)) state = GTK_STATE_INSENSITIVE; @@ -3437,23 +3438,15 @@ gtk_entry_draw (GtkWidget *widget, GTK_STATE_ACTIVE : gtk_widget_get_state (widget); if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget))) - gtk_entry_draw_frame (widget, cr); - - if (gtk_cairo_should_draw_window (cr, entry->text_area)) { + /* Draw entry_bg, shadow, progress and focus */ + gtk_entry_draw_frame (widget, cr); + + /* Draw text and cursor */ cairo_save (cr); gtk_cairo_transform_to_window (cr, widget, entry->text_area); - gtk_paint_flat_box (style, cr, - state, GTK_SHADOW_NONE, - widget, "entry_bg", - 0, 0, - gdk_window_get_width (entry->text_area), - gdk_window_get_height (entry->text_area)); - - gtk_entry_draw_progress (widget, cr, entry->text_area); - if (entry->dnd_position != -1) gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_DND); @@ -3462,35 +3455,26 @@ gtk_entry_draw (GtkWidget *widget, /* When no text is being displayed at all, don't show the cursor */ if (gtk_entry_get_display_mode (entry) != DISPLAY_BLANK && gtk_widget_has_focus (widget) && - entry->selection_bound == entry->current_pos && entry->cursor_visible) + entry->selection_bound == entry->current_pos && entry->cursor_visible) gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_STANDARD); cairo_restore (cr); - } - - for (i = 0; i < MAX_ICONS; i++) - { - EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info != NULL && gtk_cairo_should_draw_window (cr, icon_info->window)) + /* Draw icons */ + for (i = 0; i < MAX_ICONS; i++) { - cairo_save (cr); - - gtk_cairo_transform_to_window (cr, widget, icon_info->window); + EntryIconInfo *icon_info = priv->icons[i]; - gtk_paint_flat_box (style, cr, - state, GTK_SHADOW_NONE, - widget, "entry_bg", - 0, 0, - gdk_window_get_width (icon_info->window), - gdk_window_get_height (icon_info->window)); + if (icon_info != NULL) + { + cairo_save (cr); - gtk_entry_draw_progress (widget, cr, icon_info->window); - draw_icon (widget, cr, i); + gtk_cairo_transform_to_window (cr, widget, icon_info->window); - cairo_restore (cr); + draw_icon (widget, cr, i); - break; + cairo_restore (cr); + } } } @@ -4214,24 +4198,6 @@ gtk_entry_state_changed (GtkWidget *widget, if (gtk_widget_get_realized (widget)) { - GtkStateType state; - GtkStyle *style; - - style = gtk_widget_get_style (widget); - state = gtk_widget_get_state (widget); - - gdk_window_set_background (gtk_widget_get_window (widget), - &style->base[state]); - gdk_window_set_background (entry->text_area, - &style->base[state]); - for (i = 0; i < MAX_ICONS; i++) - { - EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info && icon_info->window) - gdk_window_set_background (icon_info->window, - &style->base[state]); - } - if (gtk_widget_is_sensitive (widget)) cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_XTERM); else @@ -4439,25 +4405,6 @@ gtk_entry_style_set (GtkWidget *widget, gtk_entry_recompute (entry); - if (previous_style && gtk_widget_get_realized (widget)) - { - GtkStyle *style; - - style = gtk_widget_get_style (widget); - - gdk_window_set_background (gtk_widget_get_window (widget), - &style->base[gtk_widget_get_state (widget)]); - gdk_window_set_background (entry->text_area, - &style->base[gtk_widget_get_state (widget)]); - for (i = 0; i < MAX_ICONS; i++) - { - EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info && icon_info->window) - gdk_window_set_background (icon_info->window, - &style->base[gtk_widget_get_state (widget)]); - } - } - icon_theme_changed (entry); icon_margin_changed (entry); } @@ -5567,7 +5514,7 @@ gtk_entry_draw_text (GtkEntry *entry, gint pos_x, pos_y; gint width, height; gint progress_x, progress_y, progress_width, progress_height; - + gint clip_width, clip_height; /* Nothing to display at all */ if (gtk_entry_get_display_mode (entry) == DISPLAY_BLANK) @@ -5584,6 +5531,11 @@ gtk_entry_draw_text (GtkEntry *entry, &progress_x, &progress_y, &progress_width, &progress_height); + clip_width = gdk_window_get_width (entry->text_area); + clip_height = gdk_window_get_height (entry->text_area); + cairo_rectangle (cr, 0, 0, clip_width, clip_height); + cairo_clip (cr); + /* If the color is the same, or the progress area has a zero * size, then we only need to draw once. */ if ((text_color.pixel == bar_text_color.pixel) || @@ -5771,7 +5723,8 @@ static void gtk_entry_queue_draw (GtkEntry *entry) { if (gtk_widget_is_drawable (GTK_WIDGET (entry))) - gdk_window_invalidate_rect (entry->text_area, NULL, FALSE); + gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (entry)), + NULL, FALSE); } void @@ -6707,30 +6660,6 @@ gtk_entry_set_buffer (GtkEntry *entry, gtk_entry_recompute (entry); } -/** - * gtk_entry_get_text_window: - * @entry: a #GtkEntry - * - * Returns the #GdkWindow which contains the text. This function is - * useful when drawing something to the entry in a draw - * callback because it enables the callback to distinguish between - * the text window and entry's icon windows. - * - * See also gtk_entry_get_icon_window(). - * - * Return value: (transfer none): the entry's text window. - * - * Since: 2.20 - **/ -GdkWindow * -gtk_entry_get_text_window (GtkEntry *entry) -{ - g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); - - return entry->text_area; -} - - /** * gtk_entry_set_text: * @entry: a #GtkEntry @@ -8032,9 +7961,14 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry, { GtkAllocation primary; GtkAllocation secondary; + gint frame_x, frame_y; g_return_val_if_fail (GTK_IS_ENTRY (entry), -1); + get_frame_size (entry, &frame_x, &frame_y, NULL, NULL); + x -= frame_x; + y -= frame_y; + get_icon_allocations (entry, &primary, &secondary); if (primary.x <= x && x < primary.x + primary.width && @@ -8135,41 +8069,6 @@ gtk_entry_get_current_icon_drag_source (GtkEntry *entry) return -1; } -/** - * gtk_entry_get_icon_window: - * @entry: A #GtkEntry - * @icon_pos: Icon position - * - * Returns the #GdkWindow which contains the entry's icon at - * @icon_pos. This function is useful when drawing something to the - * entry in a draw callback because it enables the callback - * to distinguish between the text window and entry's icon windows. - * - * See also gtk_entry_get_text_window(). - * - * Return value: (transfer none): the entry's icon window at @icon_pos. - * - * Since: 2.20 - */ -GdkWindow * -gtk_entry_get_icon_window (GtkEntry *entry, - GtkEntryIconPosition icon_pos) -{ - GtkEntryPrivate *priv; - EntryIconInfo *icon_info; - - g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); - - priv = GTK_ENTRY_GET_PRIVATE (entry); - - icon_info = priv->icons[icon_pos]; - - if (icon_info) - return icon_info->window; - - return NULL; -} - static void ensure_has_tooltip (GtkEntry *entry) { diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index 516b682cb3..365e409ab3 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -172,8 +172,6 @@ GtkEntryBuffer* gtk_entry_get_buffer (GtkEntry *entry); void gtk_entry_set_buffer (GtkEntry *entry, GtkEntryBuffer *buffer); -GdkWindow *gtk_entry_get_text_window (GtkEntry *entry); - void gtk_entry_set_visibility (GtkEntry *entry, gboolean visible); gboolean gtk_entry_get_visibility (GtkEntry *entry); @@ -303,8 +301,6 @@ void gtk_entry_set_icon_drag_source (GtkEntry * GtkTargetList *target_list, GdkDragAction actions); gint gtk_entry_get_current_icon_drag_source (GtkEntry *entry); -GdkWindow* gtk_entry_get_icon_window (GtkEntry *entry, - GtkEntryIconPosition icon_pos); gboolean gtk_entry_im_context_filter_keypress (GtkEntry *entry, GdkEventKey *event); diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c index dcfb62803c..2516f3dc4f 100644 --- a/gtk/gtkentrycompletion.c +++ b/gtk/gtkentrycompletion.c @@ -1400,7 +1400,14 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion) if (!window) return FALSE; + gtk_widget_get_allocation (completion->priv->entry, &allocation); + gtk_widget_get_preferred_size (completion->priv->entry, + &entry_req, NULL); + gdk_window_get_origin (window, &x, &y); + x += allocation.x; + y += allocation.y + (allocation.height - entry_req.height) / 2; + _gtk_entry_get_borders (GTK_ENTRY (completion->priv->entry), &x_border, &y_border); matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->filter_model), NULL); @@ -1436,7 +1443,6 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion) else gtk_widget_show (completion->priv->scrolled_window); - gtk_widget_get_allocation (completion->priv->entry, &allocation); if (completion->priv->popup_set_width) width = MIN (allocation.width, monitor.width) - 2 * x_border; else @@ -1455,8 +1461,6 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion) gtk_widget_get_preferred_size (completion->priv->popup_window, &popup_req, NULL); - gtk_widget_get_preferred_size (completion->priv->entry, - &entry_req, NULL); if (x < monitor.x) x = monitor.x; diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c index 849c593aef..7d11ac6e66 100644 --- a/gtk/gtkspinbutton.c +++ b/gtk/gtkspinbutton.c @@ -607,8 +607,8 @@ gtk_spin_button_realize (GtkWidget *widget) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - attributes.x = allocation.width - arrow_size - 2 * style->xthickness; - attributes.y = (allocation.height - requisition.height) / 2; + attributes.x = allocation.x + allocation.width - arrow_size - 2 * style->xthickness; + attributes.y = allocation.y + (allocation.height - requisition.height) / 2; attributes.width = arrow_size + 2 * style->xthickness; attributes.height = requisition.height; @@ -752,14 +752,15 @@ gtk_spin_button_size_allocate (GtkWidget *widget, gtk_widget_set_allocation (widget, allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - panel_allocation.x = 0; + panel_allocation.x = allocation->x; else - panel_allocation.x = allocation->width - panel_width; + panel_allocation.x = allocation->x + allocation->width - panel_width; panel_allocation.width = panel_width; panel_allocation.height = MIN (requisition.height, allocation->height); - panel_allocation.y = 0; + panel_allocation.y = allocation->y + + (allocation->height - requisition.height) / 2; GTK_WIDGET_CLASS (gtk_spin_button_parent_class)->size_allocate (widget, allocation); -- 2.30.2